﻿using System;
using System.IO;
using System.Net;
using System.Text;
using Jamhee.Noctiluca.Common;
using Jamhee.Noctiluca.LightWiki.Pages;
using Jamhee.Noctiluca.WebServer;
using Jamhee.Noctiluca.LightWiki.PropertyFiles;

namespace Jamhee.Noctiluca.LightWiki
{
    public class WikiResponser : WebResponser
    {
        private IPageHandler _pageHandler = null;
        private WikiPageHandler _wikiPageHandler = new WikiPageHandler();
        private AttachmentPageHandler _attchPageHandler = new AttachmentPageHandler();


        public override void SendResponse(HttpListenerContext context, IWebConfiguration webConfig)
        {
            // Redirect to the home page if the user requests the root of this web site
            if (context.Request.Url.AbsolutePath.Equals("/"))
            {
                if (webConfig is WikiConfiguration)
                {
                    WikiConfiguration wikiWebcfg = (WikiConfiguration)webConfig;
                    string homePage = wikiWebcfg.GetHomePage();

                    if (homePage != null && homePage.Length > 0)
                    {
                        string newURL = context.Request.Url.Scheme + "://" + context.Request.Url.Authority + "/" + homePage;
                        context.Response.Redirect(newURL);
                        context.Response.Close();
                        return;
                    }
                }
            }

            base.SendResponse(context, webConfig);
        }

        public override string ParseRequestURL(Uri requestURL, IWebConfiguration webConfig)
        {
            return WikiUtils.GetDocument(requestURL, webConfig, WikiUtils.DocType.WikiContent);
        }

        public override void ParseRequestDocument(string docPaths, HttpListenerContext context, IWebConfiguration webConfig)
        {
            string[] documents = docPaths.Split('|');
            HttpListenerResponse response = context.Response;
            Uri url = context.Request.Url;

            bool foundDoc = false;
            foreach (string doc in documents)
            {
                if (!File.Exists(doc))
                {
                    continue;
                }

                if (doc.EndsWith("\\" + WikiConstants.WIKI_DOC_CONTENT))
                {
                    // It's a wiki page
                    UrlQueryResult result = UrlQueryResult.Parse(url);

                    // Determine the page type
                    if (result.Type == UrlQueryResult.PageType.Attachment)
                    {
                        _pageHandler = _attchPageHandler;
                    }
                    else
                    {
                        _pageHandler = _wikiPageHandler;
                    }

                    // Determine the action
                    if (result.Action == UrlQueryResult.ActionType.View ||
                        result.Action == UrlQueryResult.ActionType.Edit ||
                        result.Action == UrlQueryResult.ActionType.Add)
                    {
                        _pageHandler.ParseDoc(doc, context, webConfig, result.Action);
                    }  
                    else if (result.Action == UrlQueryResult.ActionType.Save)
                    {
                        // Save pages/attachments
                        _pageHandler.Save(doc, context, webConfig);
                    }
                    else if (result.Action == UrlQueryResult.ActionType.Delete)
                    {
                        // Download pages/attachments
                        _pageHandler.Delete(doc, context, webConfig);
                    }
                    else if (result.Action == UrlQueryResult.ActionType.Download)
                    {
                        // Download pages/attachments
                        _pageHandler.Download(doc, context, webConfig);
                    }
                }
                else
                {
                    // It's not a wiki page
                    base.ParseRequestDocument(doc, context, webConfig);
                }

                // Exit if return a web page
                foundDoc = true;
                break;
            }

            // If cannot find any document, return 404
            if (!foundDoc)
            {
                response.StatusCode = 404;
                response.Close();
            }
        }
    }
}
